/**
 * 
 */
package core;

import java.net.URL;
import java.net.URLConnection;
import java.util.Observable;
import java.util.Observer;

import model.FileDownloadProgress;
import model.ThreadDownloadedInfo;
/**
 * @author Ken
 *
 */
public class DownloadComponent extends Observable implements Observer {
	public DownloadComponent() { }
	public void StartDownload(String link) {
		try {
			URL url = new URL(link);
			URLConnection conn = (URLConnection) url.openConnection();
			fileSize = conn.getContentLength();
			fileName = url.getFile().substring(url.getFile().lastIndexOf("/") + 1);
			int part = fileSize / DownloadManager.NUM_THREAD;
		
			downloadedByte = 0;
			remainThread = DownloadManager.NUM_THREAD;
			for (int i = 0; i < DownloadManager.NUM_THREAD; i++) {
				DownloadThread t;
				if (i != DownloadManager.NUM_THREAD - 1)
					t = new DownloadThread(i, url, i * part, part, fileName);
				else
					t = new DownloadThread(i, url, i * part, fileSize - (DownloadManager.NUM_THREAD - 1) * part, fileName);
				t.addObserver(this);
				Thread thread = new Thread(t);
				thread.start();
			}
			
			rateThread = new Thread(new Runnable() {				
				@Override
				public void run() {
					while (remainThread > 0) {
						try {
							Thread.sleep(1000);
							transferRate = byteInTime * 1.0f / 1024;
							System.out.println("Transfer rate = " + transferRate + "KB/s");
							byteInTime = 0;
						} catch (InterruptedException e) {						
							e.printStackTrace();
						}						
					}
				}
			});
			rateThread.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void update(Observable o, Object arg) {
		ThreadDownloadedInfo info = (ThreadDownloadedInfo) arg;
		if (info.byteDownloaded > 0) {
			downloadedByte += info.byteDownloaded;
			byteInTime += info.byteDownloaded;
		}
		else remainThread--;
		if (remainThread > 0) {
			System.out.println("Thread " + info.index + " downloaded " + info.byteDownloaded + " bytes...");
			FileDownloadProgress progress = new FileDownloadProgress((float)downloadedByte / fileSize, transferRate, 0);
			setChanged();
			notifyObservers(progress);
		}
		else {
			FileDownloadProgress progress = new FileDownloadProgress(2.0f, transferRate, 0);
			setChanged();
			notifyObservers(progress);
		}
	}
	
	Thread rateThread;
	float transferRate;
	int byteInTime;
	
	public int remainThread;
	public int fileSize;
	public String fileName;
	public int downloadedByte;	
}
